有一次在網咖查資料時,我打開某個網頁,結果裡面的文字全都是亂碼,看起來就像這樣……
我已經忘了當時是在查什麼,只記得那時候用 Google 找資料,點進去某個網站後整頁全是亂碼。
「ㄟ,這網站怎麼變這樣啊?」我忍不住問了在網咖認識的朋友。
他笑了一下,說:「很簡單啦,打開瀏覽器設定,把字元編碼改成 UTF-8 就好了。」
Note
早期可以透過瀏覽器手動設定字元編碼,但現在大部分的瀏覽器都會自動偵測並設定,因此亂碼的情況已經很少見了。
「哎!變成正常了!為什麼啊?」我問。
「阿災~反正遇到亂碼就改成 UTF-8 就對了。」他說。
當下我想說問題解決就好,所以也沒多問,哪知道隔天資訊課就教到當下我只覺得問題能解決就好,也沒多想,哪知道隔天的資訊課,老師剛好就在講「文字編碼」。
還記得前一篇提到的 ASCII 嗎?我們說過 ASCII 是一種「文字編碼」,它透過二進位對應到字母、數字和符號,讓這些內容能顯示在電腦畫面上。
不過,ASCII 早期僅支援 7 位元,也就是 2^7 = 128
個字元(代表 128 種不同符號)。這樣的限制,使得 ASCII 無法涵蓋其他語言的字元,例如中文、日文、韓文等等——畢竟它在設計之初,就是專門針對英語而來。
Note
也因為早期 ASCII 是針對英語設計的,所以後來才會改叫「US-ASCII」,意指「美國標準資訊交換碼」。
為了彌補 ASCII 的不足,後來又延伸出了「EASCII(Extended ASCII)」。那麼,EASCII 和 ASCII 有什麼差別呢?最主要的不同點是:EASCII 擴充到 8 位元,也就是 2^8 = 256
個字元,因此能支援更多符號。
由於 EASCII 是在 ASCII 的基礎上擴充而來,所以它也具備以下特性:
不過這裡要特別注意,EASCII 並不是一個國際統一標準,因為不同的系統或應用程式可能會使用不同的 EASCII 編碼方式,當時可說是「各自為政」,也因此常常引發「亂碼」問題。
以下提供一個 ASCII 與 EASCII 表格給參考:
項目 | ASCII | EASCII(Extended ASCII) |
---|---|---|
全名 | American Standard Code for Information Interchange | Extended ASCII |
位元數(bit) | 7 bits → 128 組合 | 8 bits → 256 組合 |
數值範圍 | 0 ~ 127 | 0 ~ 255 |
是否標準定義 | 是,國際標準 | 各家自定擴充 → 沒有「全球一致標準」 |
高位元區(128~255) | 無定義 | 各家放特殊符號、國際字元、圖形字元 |
主要用途 | 基本英文、數字、標點、控制碼 | 支援歐洲語言、圖形符號、商用需求等 |
那為什麼現在我們已經不用再擔心編碼問題了呢?
是因為瀏覽器夠聰明能自己辨識?還是因為電腦硬體升級了?
其實都不是,真正的原因是後來出現了「UNICODE(萬國碼)」這個標準。
這裡先破個迷思:很多人(包含以前的我)都以為 Unicode 是一種字元編碼方式。
前面介紹過的 ASCII、EASCII 確實屬於字元編碼方式,但 Unicode 實際上並不是編碼方式,而是一個「字元集」。
你可以把它想像成一本「國際字典」,收錄了世界上所有文字和符號,並且為每個字元分配一個獨特的編碼,這個編碼就叫做「碼點(Code Point)」。
例如:
字元 | 碼點(Code Point) |
---|---|
A | U+0041 |
B | U+0042 |
C | U+0043 |
你 | U+4F60 |
我 | U+6211 |
中 | U+4E2D |
😀 | U+1F600 |
🐱 | U+1F431 |
透過這樣的設計,Unicode 能夠支援全世界的文字與符號,並有效避免亂碼問題。而從上面的表格也能看出,Unicode 的碼點都是以 U+ 開頭的十六進位數字來表示。
那麼 UNICODE 所採用的位元是多少呢?
是 21 位元,這也代表 UNICODE 比 ASCII 和 EASCII 都要大得多,因為:
這樣的位元數已經足夠支援世界上所有的文字、符號等。
在前面我們說 UNCODE 是一個「字元集」,那麼它的編碼方式又是什麼呢?其實 UNICODE 有三種編碼方式:
以我們最常見使用的是 UTF-8 為例,UTF-8 的編碼方式是可變長度的,什麼是可變長度呢?
簡單來講,每個字元所佔用的位元組會隨著字元的複雜度而有所不同
這也是為什麼前面表格你會看到 A 的編碼是 U+0041,而 😀 的編碼是 U+1F600 的原因。
最後,我們也來聊聊 UTF-8 常用的進位方式-「十六進位(Hexadecimal)」。
簡單來說,十六進位就是十進位的延伸。我們知道十進位用 0~9 表示數字,超過 9 就進位。
而在十六進位中,除了 0~9 之外,還加入了 A~F 這六個字母來表示 10~15。
所以表示方式如下:
0 1 2 3 4 5 6 7 8 9 A B C D E F
關於 UTF-8,你只要先掌握幾個重點就好,其他細節有需要再去查就行:
以上就是關於 UNICODE 的基礎介紹,這樣的編碼方式讓我們可以在網路上自由地使用各種文字、符號,而不必擔心亂碼的問題囉~
當然,你也可以寫程式來查詢 UNICODE 的碼點,這邊我就以 JavaScript 為例:
document.addEventListener('keydown', (event) => {
const key = event.key;
const codePoint = key.codePointAt(0).toString(16).toUpperCase().padStart(4, '0');
console.log(`Key: ${key}, Code Point: U+${codePoint}`);
});
範例連結:https://codepen.io/hsiangfeng/pen/XJbYByG
這段程式碼會在你按下鍵盤時,顯示「按下的鍵」以及對應的 Unicode 碼點:
這裡先提醒一下讀者,因為接下來的章節會開始介紹一些程式碼與工程相關的知識,過程中可能會需要用到開發者環境,例如:
當然,你也可以選擇不安裝這些工具,單純閱讀內容也完全沒問題,只是會少了一些實作體驗。
如果你有興趣,還是建議把工具安裝起來,這樣會更有感覺。
另外也不用擔心,後面的章節並不會深入鑽研程式碼,而是以基本概念為主,輕鬆帶過就好~
本文將同步更新至以下網站: